home *** CD-ROM | disk | FTP | other *** search
/ Carousel Volume 2 #1 / carousel.iso / mactosh / hc / windoid7.sit / windoid #7.TXT
Encoding:
Text File  |  1988-10-25  |  74.2 KB  |  1,305 lines  |  [TEXT/MACA]

  1. *****      74671 0
  2. Received: from SUN.COM by WSMR07 ; 27 Sep 88 10:33:03 MDT
  3. Received: from plaid.Sun.COM by Sun.COM (4.0/SMI-4.0)
  4.     id AA28471; Tue, 27 Sep 88 09:12:32 PDT
  5. Received: by plaid.Sun.COM (4.0/SMI-4.0)
  6.     id AA07991; Tue, 27 Sep 88 09:15:34 PDT
  7. Date: Tue, 27 Sep 88 09:15:34 PDT
  8. From: hyper-hackers-request%plaid@Sun.COM
  9. Message-Id: <8809271615.AA07991@plaid.Sun.COM>
  10. To: hyper-hackers%plaid@Sun.COM
  11. Subject: Subject: Windoid #7
  12.  
  13. Subject: Windoid #7
  14. From: chuq (Chuq Von Rospach)
  15.  
  16. Editor -- David Leffler
  17.  
  18. IN THIS ISSUE:
  19.  
  20. % HyperCard Tips by Phil Wyman
  21. % Four Buttons Properties in Search of a Script by Jim Palmer
  22. % ShowMe (A Home Stack Script) by Paul Foraker
  23. % HyperCard Novice Corner by Phil Wyman
  24. % Dictionary by Ted Kaehler
  25. % HC 1.2.1 Release Notes by Mike Holm
  26. % HC 1.2.1 Release Notes by Mike Holm
  27. % The Form - to make a difference with.
  28.  
  29. ------------------------------------------------------------------------
  30. If you would like information about AHUG, please send a stamped-
  31. self-addressed-envelope to:
  32.  
  33. AHUG c/o Bryan K. Carter
  34. Apple Computer Co, Inc.
  35. MS/27-AHUG
  36. 20525 Mariani Ave. 
  37. Cupertino, CA 95014
  38.  
  39. ------------------------------------------------------------------------
  40. EDITOR'S CORNER
  41. By 
  42. David Leffler
  43.  
  44. Some of you have been wondering where WINDOID #7 was, well here it is.  If it seems to you as if there has been an unusually long time between issues, you're right, it has been.  The team has been very busy adding many of the new features you have asked for to HyperCard 1.2.1.  However, I think you will find that this issue of WINDOID will have been very much worth waiting for.  I have included in here everything I could to give you the information you need to begin using the new version of HyperCard in entirely new and wonderful ways.
  45. Bill and the entire development team have worked hard to give you something really special in this version, and I know you will be as thrilled to use it as we were to assist in its development.  
  46. There have been many changes in AHUG since the last issue.  I have stepped down as President, and Bryan Carter has emerged as the new President.
  47. Bryan works in the Engineering Support Department here in Apple Cupertino and has done an incredible job of organizing AHUG into a first class User Group. 
  48. AHUG was happy to sponsor the first public showing of HyperCard v1.2 on May 5.  Bill, Dan, and the HyperCard Team wowed a standing-room-only crowd of 350+ very enthusiastic HyperCard users.  The two most admired features were CD ROM/ FileServer compatibility as well as enterInField and returnInField.
  49. On July 8th,  author Danny Goodman showed us his soon-to-be released book "Danny Goodman's HyperCard Developer's Guide". Danny's book takes a three part, in-depth look at implementing and designing stacks from a user interface point of view.  Danny also hinted about an upcoming update to his acclaimed Focal Point time/project management stack.
  50. Additionally and importantly, for those of you that are interested in XCMD's and XFCN's, Gary Bond's book "XCMD's for HyperCard", published by MIS: Press, is required reading.  No question, it's the best!
  51.  
  52. %JFuture meetings of AHUG will feature guests from Apple Computer, HyperPro, Personal Training Systems, SuperMac Technologies, HyperAge, MacUser, and MacWorld magazines. 
  53.     
  54. % A major AHUG announcement will be made at MacWorld '88 in Boston. Future issues of WINDOID will have more information.
  55.  
  56. % AHUG has a new telephone number for you to call if you would like to obtain information on the AHUG meeting times and forthcoming agenda.  The number is 408-974-1707.
  57.  
  58. %Please remember that the purpose of this newsletter is to help you help us to make a quality difference in the world. We provide a unique opportunity for WINDOID readers to contribute directly to the ongoing growth and excellence of Apple's HyperCard*. 
  59. There is a form at the back of this, and every, issue of WINDOID that allows you to communicate directly with the HyperCard Team.  We really want your input.  We want to know what you like, and what you don't like, about HyperCard and what features or suggestions you would like to see implemented in future versions.  We give you this unique opportunity because we care about you.  For those that wrote to us and participated in HyperCard 1.2.1, we thank you.  I believe that you will be very pleased you took the time to make yourself heard.
  60.  
  61. For those of you that would like additional copies of this WINDOID, or back issues, you must send us a stamped-self-addressed-envelope for each one.  We will be unable to send you anything without them.  If you send us a very large manilla envelope for all of the issues, please put on enough postage for about fifty (50) pages. 
  62. Bryan is putting together a mailing list and will be telling you how to receive regular copies as I publish them. Again, if you like HyperCard and WINDOID, please let us know.  You will be glad you did.
  63.  
  64. ------------------------------------------------------------------------
  65. HYPERCARD USER TIPS
  66. by 
  67. Phil Wyman
  68.  
  69. 1. In earlier WINDOIDs, I mentioned that you can get a bit-mapped miniature of your Card by copying the card, then doing a CMD-Shift-Paste.  However, to do this automatically through HyperTalk, you should try:
  70.     DoMenu  "Copy Card"
  71.     type "v" with commandKey,shiftKey
  72.  
  73. 2. Here is a short example of the usefulness of the "do" command:  If you have a variable x with a value of "field id 1", then you can say in your script,
  74.  
  75.     get line 1 of x 
  76.     
  77. What you would get in this instance is the words "field id 1", the text that was in the variable x. In order to get what you really wanted, namely the first line of field id 1, you must issue a "do" command like the following:
  78.  
  79.     do "get line 1 of " & x
  80.  
  81. 3. Be aware that when you create a new card, the openCard message gets sent before the newCard message.
  82.  
  83. 4. Developer tip:  Test your stacks at every userlevel. This is important since you will probably develop at userLevel 5, which will work fine until a user is in browse mode.  A typical example of this problem is if you have a DoMenu "Copy Card" in your script. This will cause an error at the lowest userLevels which do not have that menu choice. A workaround to this is to, on openstack,  put the current userLevel  into a variable, and then set userLevel to 5.  Make sure you set it back to the previous userLevel when you leave your application. 
  84.  
  85. 5. If you try to go to card foo, and there is no card named foo, HyperCard will not make a fuss.  However, you can find out that HyperCard has not found the card by checking "the result".  "No such card" is "the result" if the card is not found.
  86.  
  87.     go card foo
  88.     if the result is "no such card"
  89.     then answer "Card not found"
  90.  
  91. 6. A returnKey handler intercepts the returnKey when it is hit in the message box, whether there's a message in the message box or not.  So when you're using a returnKey handler, take into account that the user may well be sending a message through the message box. I found that I had to look to see if the msg was empty before I did my normal returnKey handler, since I didn't want the returnKey handler to execute if the user was sending another message.  The same is true for an enterKey handler.
  92.  
  93. 7. When you hit the grave character in HyperCard, you normally "go back" to the last card you were on. If you wanted a grave character, however, you can type Option-Grave-Spacebar in Geneva 12.  For fun, try Shift-Option Grave in Geneva 12.  (It gives you a little bunny rabbit in the field. With Geneva 14 you get a bird, with Geneva 18 you get a sheep, and with Geneva 20 you get a Macintosh computer.)
  94.  
  95. 8. Here are some button ideas:
  96. This first button idea is a working radio card button.  The radio button checks to see if there are any more radio buttons on, since only one radio button should be on at a time.  Put the following script in a button. Set the style to radio button and autoHighliting to true in the button info dialog box.  The script  checks first to see if the button which was clicked on is highlited. If it is highlited, nothing happens, since a series of radio button should always have at least one button on.  If the button is not highlited, then this script hilites it and turns off all the rest of the buttons on the card.  This script assumes that you only have one series of radio buttons on each card, and that all of them are card buttons. 
  97.   
  98. on mouseUp
  99.   if not the highlite of me then
  100.     repeat with x = 1 to the number of buttons
  101.       if the style of button x is "radioButton" then
  102.         if the highlite of button x then
  103.           set the highlite of button x to false
  104.        end if
  105.       end if
  106.     end repeat
  107.     set the highlite of me to true
  108.   end if
  109.  end mouseUp
  110.  
  111. The second button idea is a working check box.  All the check box does is go on or off.  I found it very difficult to figure out that to get a check box to go on or off, you had to click the autohighlite feature in the button info dialog. 
  112.  
  113. 9. If your HyperCard home card doesn't look just like it does in the manual, then you need Times 18 font in your system so that the words "HOME CARD" will appear in the proper font.
  114.  
  115. 10. There is an easy way to append to a file in HyperTalk.  Read until it is empty, then do your write command.
  116.     
  117. ------------------------------------------------------------------------FOUR BUTTON PROPERTIES IN SEARCH OF A SCRIPT
  118. by 
  119. Jim Palmer (with excellent refinements by Clifford Guren)
  120.  
  121. Setting the text properties of buttons-the textFont, textSize, textAlign, and textStyle properties-is currently accomplished via the grace of the message box.   You must type a sequence of the set command as follows:
  122.     set textFont of button "Sample Button" to Helvetica
  123.     set textSize of btn "Sample Button" to 14
  124.     set textStyle of btn "Sample Button" to bold
  125.     textAlign of btn "Sample Button" to center
  126. This article describes a script that lets you set the text properties of buttons using the same Text Style dialog box used to set the text properties of fields and paint text.  In addition, the script uses some of the new features in HyperCard 1.2.1 , including the within operator and many of the new synonyms.
  127. The script has only two parts, (1) a message called buttonFont that performs most of the work and (2) a function called getButton that returns the name of a button the user chooses with a click. 
  128. When you call buttonFont, the basic algorithm is as follows:
  129. %  ButtonFont changes the cursor to the Arrow cursor to indicate that you should choose a button.  It then waits for you to click the mouse.  
  130. %  After you click the mouse, buttonFont calls the function getButton, which returns the name of the button you have chosen.  If getButton returns the empty string, you did not click a button, so buttonFont exits.
  131. %  ButtonFont then gets the current text properties of the chosen button and saves them as default settings.
  132. %  Next, buttonFont locks the screen, chooses the Text tool, and sets the text properties to the default values.  It then brings up the Text Style dialog box with each text property set to the value of the default settings (that is, the text properties of the button).  You can then use the dialog box to make any changes to the text properties.  Note that textHeight is not a property of buttons, so its value is not used by buttonFont.
  133. %  After you finish with the Text Style dialog, buttonFont reads the new values of the text properties.  It then sets the text properties of the button to these values.  Note that if you canceled the Text Style dialog box, the values are just those of the default setting, so the button's text properties are not changed.
  134. %  Finally, buttonFont chooses the Browse tool and unlocks the screen.  
  135.   Since no mouse events are sent while the buttonFont message is running, the function getButton uses HyperCard 1.2.1's new within operator to determine whether you clicked a location on the screen that is within the region of a button:
  136. %  getButton takes one argument, the point where you last clicked (the clickLoc).
  137. %  It then goes through all the card buttons using within to see if the point is inside the rect of any of these buttons.  If so, it returns the name of the card button.
  138. %  If getButton did not return, it then goes through all the background buttons using within to determine if the point is inside the rect of any of these buttons.  If so, it returns the name of the background button.
  139. %  Finally, if getButton did not return, it returns the empty string because you did not click a button.
  140. To get the most use of the buttonFont message, you will probably want to copy it, and getButton, into the script of your Home stack.  There are several ways that you might call it.  One is to assign it to a function key.  For example, putting the following code in your Home stack lets the F7 key invoke the message:
  141.  
  142. on functionKey whatKey
  143.    if whatKey is 7 then
  144.      buttonFont
  145.    else
  146.      --any other function key assignments
  147.    end if
  148. end functionKey
  149.  
  150. If you don't have function keys, you can assign buttonFont to the key command Option-T (to relate it to Command-T, the key command that brings up the Text Style dialog box).  Because HyperTalk cannot trap for a single key press, you will have to press Option-T and then the Return key to send the message.  This works best if the property Blind Typing from the User Preferences card is set to true so that the message box does not have to be visible when you type Option-T.  The following code lets Option-T invoke buttonFont (where Option-T is the character  ):
  151. on  
  152.    buttonFont
  153. end  
  154.  
  155. Finally, here are a few things to note about using the buttonFont message:
  156. %  Buttons in the following script cannot have more than one textStyle property; for example, they can be bold or condense, but not bold and condense.  The Text Style dialog box, however, allows users to choose more than one text style because fields and paint text can have more than one style.  If users forget and set more than one style for a button, buttonFont only uses the first (or topmost) style.
  157. %  The text properties of buttons do not affect the text that is displayed when a button shows an icon.
  158. %  The appearance of a given font depends on the fonts currently installed in the System.  For example, if a user sets a button's font to Times but does not have Times in his System, an automatic font substitution will occur.
  159. %  With HyperCard 1.2.1, stacks can be write-protected.  If a stack is write-protected, none of the choices in the Text Style dialog box are active, so you can't actually change the text properties of the button.
  160. %  To cancel the buttonFont message before you actually select a button, just click where there is no button (or use Command-period).
  161. buttonFont message and its auxiliary function for HyperCard Version 1.2.1
  162.  
  163. on buttonFont
  164.   put empty into btnName
  165.   set cursor to arrow -- pointing cursor 
  166.   -- see if the user selects a button:
  167.   wait until the mouseClick
  168.   set cursor to watch
  169.   put getButton(the clickLoc) into btnName
  170.   if btnName is not empty then -- then the user has
  171.   --chosen a button
  172.  
  173.   -- get all of its current properties:
  174.     put the textfont of btnName into font
  175.     put the textsize of btnName into size
  176.     put the textstyle of btnName into style
  177.     put the textalign of btnName into align
  178.  
  179.     -- now lock the screen, choose the Text tool, 
  180.     -- and set defaults:
  181.     lock screen
  182.     choose text tool
  183.     set textfont to font
  184.     set textsize to size
  185.     set textstyle to style
  186.     set textalign to align
  187.  
  188.     -- bring up the Text Style dialog box:
  189.     type "t" with commandKey
  190.  
  191.     -- get the results of the Text Style dialog:
  192.     put the textfont into font
  193.     put the textsize into size
  194.     put the textstyle into style
  195.     put the textalign into align
  196.  
  197.     -- set the button accordingly:
  198.     set textfont of btnName to font
  199.     set textsize of btnName to size
  200.  
  201.     -- trap for multiple styles:
  202.     if the number of items of style > 1 then
  203.       put item 1 of style into style
  204.     end if
  205.     set textstyle of btnName to style
  206.     set textalign of btnName to align
  207.  
  208.     -- clean up:
  209.     choose browse tool
  210.     unlock screen
  211.   end if
  212. end buttonFont
  213.  
  214. function getButton clickPoint
  215.   -- check all card buttons:
  216.   repeat with i = 1 to the number of buttons
  217.     if clickPoint is within rect of card btn i then
  218.       return the name of btn i
  219.     end if
  220.   end repeat
  221.  
  222.   -- if it hasn't returned yet, then it wasn't a card button;
  223.   -- check all background buttons:
  224.   repeat with i = 1 to the number of background buttons
  225.     if clickPoint is within rect of bg btn i then
  226.       return the name of bg btn i
  227.     end if
  228.   end repeat
  229.   -- if it hasn't returned yet, it wasn't a button:
  230.   return empty
  231. end getbutton
  232.  
  233. ------------------------------------------------------------------------ShowMe
  234. A Home Stack Script 
  235. by 
  236. Paul Foraker
  237.  
  238.  
  239. I recently had the pleasure of developing a set of 19 stacks for a client. These stacks were moderately complex, including a context-sensitive help system using hidden fields and buttons. It was easy to lose track of which objects we'd already put on the cards, so I wrote this script to add to the handlers in my Home stack script. Now I can simply type "showMe" into the message box in any stack, and HyperCard will come back with a list of all the objects (including hidden objects) on the card I'm looking at and put the list into a card field that the script draws for that purpose.
  240.  
  241. Editor's Note:Option-Return looks like a little box at the end of a line.
  242.  
  243. -- ShowMe
  244. -- 3/24/88 version 0.4
  245.  
  246. -- ShowMe makes a list of all the objects of the current
  247. -- card and background and puts them in a card field named
  248. -- "objects list". Copy this script into your Home stack,
  249. -- then you can type "showme" into the message box while
  250. -- you're looking at any card.
  251. on showMe
  252.   set cursor to 4 -- wristwatch or set cursor to watch in 1.2.1.
  253.   --  "objectNames" will be the variable we'll load up to contain
  254.   -- the names of the objects on the card.
  255.   -- First, the title:
  256.   put "Objects of " & the name of this card & return & returnB
  257.   into objectNames
  258.  
  259. -- BACKGROUND FIELDS
  260.  
  261.  -- Then, we get the field names (if any).
  262. if the number of fields <> 0 then
  263.   repeat with i = 1 to the number of fields
  264.  -- in order to tell whether a field is hidden or not, weUll
  265.  -- use a variable called "showing". We'll begin by making it
  266.  -- empty.
  267.     put empty into showing
  268.  -- Now, for each field, we're putting either nothing or "hidden"
  269.  -- into "showing".
  270. if not the visible of field i then put "[hidden]" into showing
  271.  -- The construction "not the visible of field i" resolves to
  272.  -- either true or false depending whether the field is hidden
  273.  -- or visible.
  274.  -- Now we add the field name, whether it is visible or not, and a
  275.  -- return to our variable "objectNames".
  276.     put the name of field i && showing & return after objectNames
  277.   end repeat
  278. end if
  279.  -- Here, we're going to write a "graphic" element to indicate the
  280.  -- end of the list of fields.
  281. put "=====" & return after objectNames
  282.  
  283. -- BACKGROUND BUTTONS
  284.  
  285.     -- Using the same routine we did for the background fields:
  286.   if the number of background buttons <> 0 then
  287.     repeat with i = 1 to the number of bkgnd buttons
  288.       put empty into showing
  289.       if not the visible of background button i thenB
  290.       put "[hidden]" into showing
  291.       put the name of background button i && B
  292.       showing & return after objectNames
  293.     end repeat
  294.   end if
  295.     -- again, this is the graphic element that indicates the end
  296.     -- of the list of background buttons.
  297.   put "=====" & return after objectNames
  298.  
  299. -- CARD FIELDS
  300.  
  301.   if the number of card fields <> 0 then
  302.     repeat with i = 1 to the number of card fields
  303.       put empty into showing
  304.       if not the visible of card field i thenB
  305.       put "[hidden]" into showing
  306.       put the name of card field i && showing & returnB
  307.       after objectNames
  308.     end repeat
  309.   end if
  310.   put "=====" & return after objectNames
  311.  
  312. -- CARD BUTTONS
  313.  
  314.   if the number of buttons <> 0 then
  315.     repeat with i = 1 to the number of buttons
  316.       put empty into showing
  317.       if not the visible of button i thenB
  318.       put "[hidden]" into showing
  319.       put the name of button i && showing &B
  320.       return after OBJECTNAMES
  321.     end repeat
  322.   end if
  323.   
  324. -- PUTTING THE LIST INTO A CARD FIELD
  325.  
  326.         -- Okay, we've got the entire list of objects. Now, we
  327.     -- check the list to see if it already contains a card field
  328.     -- named "object list". If it does, then we put our list into
  329.     -- that field and we're done.  If it does not, then we make
  330.     -- the new card field on the fly and put our list into it.
  331.   
  332.   if OBJECTNAMES contains "object list" then
  333.     put OBJECTNAMES & return & return into card field "object list"
  334.     show card field "object list"
  335.     exit showMe
  336.   end if
  337.  
  338. -- MAKING A NEW CARD FIELD
  339.  
  340.   doMenu "new field"   -- makes a new card field
  341.     -- Since new cards are unnamed (unlike buttons, which get the
  342.     -- name "new button"), we'll refer to the field by number. If
  343.     -- we already had, for example, three card fields on the card,
  344.     -- our new field will be number 4. Rather than keep track of
  345.     -- how many card fields we have on this card, we simply refer
  346.     -- to the function, number of, knowing that the number of
  347.     -- card fields has been increased by one. We could write:
  348.     -- get the number of card fields
  349.     -- then use that number to refer to our new field. But,
  350.     -- more directly, we simply put "the number of card fields"
  351.     -- in parentheses where we want HyperCard to count the card
  352.     -- fields, and we end up with:
  353.   set name of card field (the number of card fields) to "object list"
  354.     -- Now that we have a name for our new card field, we can refer
  355.     -- to it by its name. Next step is to tell HyperCard
  356.     -- what the properties of the field should be.
  357.   set rect of card field "object list" to 0,0,258,342
  358.   set style of card field "object list" to scrolling
  359.   set textfont of card field "object list" to geneva
  360.   set textsize of card field "object list" to 9
  361.     -- Now we put our variable into the field.
  362.   put OBJECTNAMES into card field "object list"
  363.     -- The field that weUve drawn on the card is pretty big. It
  364.     -- stretches from the upper left corner to about 1/3 of
  365.     -- the way across the card at the bottom. If we want to see
  366.     -- what's underneath the scrolling field, we have to hide
  367.     -- the field. So, we put a handler in the fieldUs script
  368.     -- that lets us do that. This handler hides "the target"
  369.     -- (the object that got the mouseUp message) and also
  370.     -- puts a command into the message box, ready for us to
  371.     -- type a return. That command shows the hidden field again.
  372.   put "on mouseUp" & return &B
  373.   "hide the target" & return &B
  374.   "put" && quote & "show" & quote && " && the name of the target" B
  375.   & return & "end mouseUp" & return into temp
  376.     -- I put the script into the variable "temp" first,
  377.     -- so the next line of HyperTalk code will be simple
  378.     -- and straightforward.
  379.   set script of card field "object list" to temp
  380.     -- Now we lock the field so we can click on it.
  381.   set locktext of card field "object list" to true
  382.     -- And weUre all done, so letUs get back to our browsing.
  383.   choose browse tool
  384. end showMe
  385.  
  386. ------------------------------------------------------------------------HyperCard Novice Corner 2
  387. by
  388. Phil Wyman
  389.  
  390. One of the most powerful features of HyperCard is clicking a button which will go to a card.  Even a novice can make such a button. This feature requires no programming, yet can allow you to create useful stacks. This feature can also be called "linking," but that word is way too scary for us novices. "Linking" brings thoughts of relational databases and high powered programmers.  However, we can "link" a button to a card with very little effort in HyperCard. 
  391. Starting on the Home card click on the left arrow and click on Authoring.  Click on the right arrow to go back Home.  
  392. Click and hold the mouse down on the word "Edit", which is in the menu bar above to your left.  We are activating the Edit menu. Drag the mouse down within the menu until the words "New Card" are highlited.  Am I going too fast for you?  Let up the mouse.  We should have created a new card in your Home stack. We should now be on a blank white card.
  393.  We will now use another menu, "Objects".  We learned to use menus in the preceding paragraph. So, click and hold on the word "Objects" in the menu bar at the top of the screen. Drag the mouse down to the words RNew buttonS and release.  A new button should now be in the middle of the card.  
  394. A couple of miraculous things have happened. One thing is that we are now in the Button tool instead of the Browse tool. We can confirm this by clicking on the "Tools" menu, and you will notice that the button in the middle of the first row is highlited, not the image of the hand (the Browse tool).  Let up the mouse.  The other great thing that has happened is that there are dots moving all around the new button we just created! These are affectionately known as "marching ants."  When these "marching ants" are around a button, it tells you that this button is the one we can work on.  You can only work on one button at a time, so only one button will have the "marching ants" at any given time.
  395. Now, click and hold on the word "Objects" in the menu bar again.  Notice that the words "Button Info" have been darkened and are no longer gray. This means that "Button Info" is active, so letUs drag the mouse down until the words "Button Info" are highlited. Let up the mouse.
  396. A dialog box appears on your screen, giving you information about your button.  If you start typing, you can give your button a name. There is a button on the dialog box which says "LinkTo...".  I want you to click on this button. A small window appears which says: "This Card" ; "This Stack" ; "Cancel".  At this point in the "linking" process, we want to go to the card which we want the button to take us to when we click on it. If this is confusing,  it should clear up in the next couple of steps.  
  397. From the "Go" menu, choose "Home". This will take us to the "Home" card.  Click on "This Card" in the small window.  You will be returned to the card with your "new button" on it. From the "Tools" menu in the menu bar, drag on to the image of the hand and let up the mouse. This will put you in the Browse tool, and the marching ants around your button should disappear. You have successfully linked this button with your Home card.  Now, every time you click this button, you will go to your Home card! Try it.
  398. This linking of a button to a card has many possibilities.  For instance, the button we just named could be called "Home", and every time we click on it, we go to our Home card. In the same way, we could make a button called "giraffe", which goes to a card which has a picture and information of a giraffe. Linking with buttons creates a concept of "navigation", which allows users to quickly go where they want to in your stack.
  399.  
  400. ------------------------------------------------------------------------DICTIONARY
  401. by 
  402. Ted Kaehler
  403.  
  404. Part 1
  405. One of the most useful things a computer can do is look up an item in a dictionary.  Like a simple database, a dictionary is a table with two columns.
  406. A script looks up a key in one column and reads off the value from the other column.  If the word dictionary does not seem to fit well (it does not contain any definitions), think of a Spanish-English dictionary.  There are many different situations in which a quick translation from one thing to another is useful.  If you are building an automatic table of contents for a stack, you might want to translate between titles of cards and card ID numbers.  In a spread sheet, you might want to translate names of cells into field numbers.
  407.  Suppose you have an address stack that contains formal names like "Robert," "William," and "Elizabeth."  When you use the Find command, you really want to type nicknames like "Bob," "Bill," and "Liz."  LetUs write a script that translates the informal names you type into the formal names that appear in an address stack.
  408.  A simple way to build a dictionary is to make two lists.   The nicknames are
  409. separate words in one list, and the formal names are the corresponding words of the other.  The lists are stored in variables.  The lookup function steps through the words of the nickname list.  When it finds the name you asked for, it looks for the word in the same position in the formal name list.
  410.  
  411. First let's make a function that takes a key and two lists.  It looks the key up in the first list and returns a translation from the second:
  412.  
  413. function lookup key, listOfKeys, listOfAnswers
  414.    repeat with ii = 1 to the number of words of listOfKeys
  415.       if key = word ii of listOfKeys
  416.       then return word ii of listOfAnswers
  417.    end repeat
  418.    return key -- return the key if it is not in the list
  419. end lookup
  420.  
  421. Here is the way its used:
  422.  
  423.     put "Bob Bill Liz" into nickNames
  424.     put "Robert William Elizabeth" into formalNames
  425.     put lookup(word 1 of it, nickNames, formalNames) into word 1 of it 
  426.  
  427. -- Editor's Note: Sorry, the above line wrapped and shouldn't be.
  428.  
  429. Now, we need to hook this fragment of script to the Find command in our address stack.  LetUs intercept the Find command and translate the first word of the search key.  (Note that the Find command actually has two arguments.  The first is a number that keeps track of what kind of Find it is.  This number is inserted behind our backs, and all we have to do is know to give it a name.) This script will work in all versions of HyperCard.
  430.  
  431. on find dummy,key
  432.    -- dummy is used privately by HyperTalk
  433.   send "find" && quote & key & quote to HyperCard
  434.   if the result is "not found" then
  435.     put "Bob Bill Liz" into nickNames
  436.     put "Robert William Elizabeth" into formalNames
  437.     put key into newKey
  438.     put lookup(word 1 of newKey, nickNames, formalNames) into
  439.        word 1 of newKey
  440.  
  441.  -- Editor's Note: Sorry, the above line wrapped and shouldn't be.
  442.  
  443.     if newKey is not key -- if word 1 was translated
  444.     then send "find" && quote & newKey & quote to HyperCard
  445.   end if
  446. end find
  447.  
  448. The script first sends the original Find command directly to HyperCard.  If the Find succeeds, do nothing further.  If the Find fails, then look up word 1 of the key and substitute it in.  If this substitution changes what we are looking for, then search on the new translated version.
  449.  
  450. Next, weUll refine this example to make it faster and more elegant.
  451.  
  452. Part 2            
  453.  
  454. LetUs build a more powerful dictionary for converting a key into a value.  The key may contain more than one word, and there may be multiple keys (synonyms) for the same value.  WeUll make the dictionary lookup go fast by using the "offset()" function to find the key in the dictionary.  Users can decide if the key should be matched completely, or if it need only match the beginning of an entry (like the Find command).
  455.  
  456. To allow multiple words in keys and values, we canUt use space as the separator between entries in the dictionary.  The characters { } and | are not used very much and are unlikely to appear in the things you want to put in your dictionary, so weUll use them as separators.  A dictionary entry with several keys and a value will be a single piece of text.  Every key has a { in before and after it, and the value has a | just before it and } just after it.  
  457.  
  458. Here is the entry that translates nicknames for Elizabeth:
  459.       {Liz{Beth{Betty{|Elizabeth}
  460.  
  461. Don't include spaces in a dictionary entries unless you want them to be part of a key or a value.  Each entry can be on a separate line if you wish.
  462.  
  463. Let's modify an address stack to translate from nicknames to formal names. We'll keep the dictionary in a global variable called "NickNames".  Here is the script that creates the dictonary when you enter the stack:
  464.  
  465. on openBackground
  466.   global NickNames
  467.   put "{Bob{|Robert}  {Bill{|William}  {Mike{|Michael} " &
  468.   "{Liz{Beth{Betty{|Elizabeth}   {Tom{|Thomas}" &
  469.   "{Jim{|James}  {Dave{|David}  {Joe{|Joseph}" into NickNames
  470. end openBackground
  471.  
  472. Next, let's build a function that does the actual work of looking up a key in the dictionary.  The "translate" function takes a key and a dictionary as arguments and returns the value for that key.  If the key is not in the dictionary, the function returns the key unchanged.
  473.  
  474. function translate key,dictionary,exact
  475.   put "{" & key into realKey  -- {Liz
  476.   if exact is empty           -- look for exact match
  477.   then put offset(realKey,dictionary) into index       -- loc of {Liz. . .
  478.   else put offset(realKey &"{",dictionary) into index  -- loc of {Liz{
  479.  
  480.     -- if the key wasnUt found, give back the original key
  481.   if index is 0 then return key     -- Liz
  482.   put char index to (index+200) of dictionary into local
  483.     --   {Liz{Beth{Betty{|Elizabeth}  {Tom{|Thomas...
  484.   put offset("|",local) into numStart     -- 17
  485.   put offset("}",local) into numEnd       -- 27
  486.   return char (numStart+1) to (numEnd-1) of local -- Elizabeth
  487. end translate
  488.  
  489. The first half of the translate script sets "index" to the location of the
  490. beginning of the key in the dictionary.  The second half pulls out a section of the dictionary into the variable "local" in order to work on it.  Currently, an entry in the dictionary canUt be longer than 200 characters (for keys and value).  To allow longer entries, change the "200" to a bigger number.  The script finds the | at the beginning of the value part of the entry.  Then it finds the next } at the end of the entry.  It returns the characters from the beginning to the end of the value it found.
  491.  
  492. The third argument is optional.  If you leave it off, the first argument only has to match the beginning of a key in the dictionary (just like the Find command).  If you call translate with anything as the third argument, then the key will only be translated if it matches exactly.
  493.  
  494. Here are some sample calls: 
  495.     put translate("Betty", NickNames)
  496.     put translate("Mik", NickNames,"exact")
  497.  
  498. Mik is not translated to Michael in the second example because we specified an exact match.  Remember to put double-quotes around a key if it has any spaces in it.  Put the translate function in your home script, and use it with all kinds of different dictionaries.
  499.  
  500. Here's how an address stack would use translate to convert nicknames to formal names for the Find command:
  501.  
  502. on find dummy,key
  503.     -- dummy is used privately by HyperTalk
  504.   send "find" && quote & key & quote to HyperCard
  505.   if the result is "not found" then
  506.     global NickNames
  507.     put key into newKey
  508.     repeat with jj = 1 to the number of words in key
  509.       put translate(word jj of key,NickNames) into newWord
  510.       put newWord into word jj of newKey
  511.     end repeat
  512.  
  513.     if newKey is key then beep
  514.     else
  515.       send "find" && quote & newKey & quote to HyperCard
  516.       if the result is "not found" then beep
  517.     end if
  518.   end if
  519. end find
  520.  
  521. This script first tries a normal HyperCard Find on the key.  If it is found, do nothing more.  If the key is not found, then for each word in the key, translate it through the dictionary NickNames and substitute in the translated word.  If the translation (newKey) is the same as the original (key), then none of the words were in the dictionary.  Since the first search failed, beep and exit.  Otherwise, Find using the new key.  If it also canUt be found, then beep.  (Since we are calling Find from a script, it does not beep by itself.)
  522. Notice that the script always replaces a word in the key with its translated value.  Since words that are not in the dictionary come back from the translate function unchanged, this works.
  523.  
  524. Put the translate handler in your Home script to use from many stacks with many different dictionaries.  The modified Find handler goes in an address stack. It doesn't belong in the Home script because most Finds have nothing to do with names of people.   A quick translation from one set of terms to another is a very useful tool to have in your scripterUs bag of tricks.  When you're building a stack and suddenly realize that a translation would help, think of these scripts.
  525.  
  526. ------------------------------------------------------------------------
  527. HYPERCARD VERSION 1.2.1 FINAL PROGRAMMER'S NOTES 
  528. by 
  529. Mike Holm of Apple Computer Co, Inc,
  530. ) Copyright Apple Computer Co, Inc. 1988
  531.  
  532. These notes contain information of interest to stack designers and programmers that are not covered in the general HyperCard Version 1.2 Release Notes Stack.  Features visible to the average user are described in the Release Notes Stack.  The HyperCard version 1.2.1 Final Programmer's Notes  include the following:
  533. %  New HyperTalk synonyms.
  534. %  New HyperTalk commands, properties and functions.
  535. %  Using "peeking" for fast script review and editing.
  536. %  Performance improvements in finding text and navigat-
  537.      ing stacks.
  538. %  User-visible bug fixes.
  539. %  Miscellaneous notes on write-protected media and
  540.      stacks, and related design considerations.
  541.  
  542. Briefly, HyperCard 1.2.1 includes the following new features:
  543. %  On locked stacks, HyperCard 1.2.1 distinguishes between user actions and those of HyperTalk scripts.  While users are prevented from making changes to a locked stack (unless the new property userModify is set to true), its scripts can perform most operations.  Changes created in locked stacks are temporary-they disappear when the user leaves the card to which changes have been made.  Specific restrictions imposed by locked media are explained in detail later in this document.
  544. %  Performance and robustness in handling large stacks has been greatly improved.  To take advantage of these improvements, stacks created with older versions of HyperCard should be compacted twice with version 1.2.1.
  545. %  Pictures on cards and backgrounds can now be hidden and shown.  New HyperTalk commands allow stack designers to hide or show art (just like buttons or fields) as part of a HyperTalk script.
  546. %  Visual effects work with HyperTalk"s new Unlock Screen command.  Stack designers may now have a button, field or picture appear or disappear with a visual effect rather than just "popping up."
  547. %   Many  HyperTalk synonyms, commands and properties have been added or extended.
  548. %  HyperCard 1.2.1 allows fast access to HyperTalk scripts by "peeking."  Users and designers may quickly view and edit scripts.
  549.  
  550. New HyperTalk Abbreviations:
  551.  
  552. %  cd = card (get the number of this cd)
  553. %  bg = background (number of cards of this bg)
  554. %  fld = field (hide fld 3)
  555. %  cds = cards (number of cds)
  556. %  bgs = backgrounds (number of bgs)
  557. %  flds = fields (number of flds)
  558. %  btns = buttons (number of btns)
  559. %  second = seconds (wait 1 second)
  560. %  sec = secs (wait 1 sec)
  561. %  tick = ticks (wait 1 tick)
  562. %  pict = picture (hide card pict)
  563. %  grey = gray (dissolve to grey)
  564.  
  565.  
  566. New HyperTalk Messages
  567.  
  568. %  returnInField
  569. This message is sent to the field when the Return key is pressed while there is an insertion point or selection in a field.  If returnInField is not intercepted by a handler and the insertion point or selection is on the last line of the field, HyperCard will check to see if the field has "autoTab" set to true.  If so, HyperCard sends a "tabKey" message to the current field.  If the tabKey message is not intercepted by a handler, the cursor will move to the next field.  If the insertion point or selection is not on the last line of the field, or if autoTab is false, a carriage return will be inserted in the text of the field.
  570.  
  571. on returnInField -- when the Return key is pressed prevent insertion
  572.   -- of carriage returns anywhere in the field
  573. end returnInField
  574.  
  575. %  enterInField
  576. The enterInField message is sent to a field when the Enter key is pressed while there is an insertion point or selection in a field.  If enterInField is not intercepted by a handler and the contents of the field have been changed, HyperCard sends a closeField message. 
  577.  
  578. on enterInField   -- when the enterKey is pressed find the field
  579.   --contents in another stack
  580.  get me
  581.  go to stack "Address"
  582.  find it
  583. end enterInField
  584.  
  585.  
  586. New HyperTalk Commands
  587.  
  588. %  Find Whole "string to be found"
  589. Unlike the general Find command, Find Whole uses both word starts and word endings in finding the chosen text.  Find Whole also uses space characters in the string.  See the HyperCard Version 1.2 Release Notes stack for a description of Find Whole.
  590.  
  591. %  Find String "string to be found"
  592. Find String finds characters specified in a string, ignoring word boundaries.
  593.  
  594. Find String "ple"  -- would find the string of characters "ple"
  595.  
  596. For strings without spaces, it works the same way as Find Chars.  When a string has a space followed by at least three other characters, Find String uses HyperCard"s fast search algorithm.
  597.  
  598. Find String "ple" offers the same performance as  
  599. Find Chars "ple".
  600.  
  601. Find String "ple comp"  is much faster because the space and characters in "ple comp" invoke HyperCard"s fast search.  
  602.  
  603. %  hide picture of <card expression>
  604. This command will hide the card picture specified in the card expression.  For example:
  605.  
  606. on mouseUp
  607.   hide picture of card 3
  608. end mouseUp
  609.     
  610. %  hide picture of <background expression>
  611. This command will hide the background picture specified in the background expression.  For example:
  612.  
  613. on mouseUp
  614.   hide picture of background 3
  615. end mouseUp
  616.     
  617. %  show picture of <card expression>
  618. This command will show the card picture specified in the card expression.  For example:
  619.  
  620. on mouseUp
  621.   show picture of card 3
  622. end mouseUp
  623.  
  624. %  show picture of <background expression>
  625. This command will show the background picture specified in the background expression.  For example:
  626.  
  627. on mouseUp
  628.   show picture of background 3
  629. end mouseUp
  630.  
  631. %  hide card picture
  632. This hides the picture on the current card.  For example :
  633.  
  634. on mouseUp
  635.   hide card picture
  636. end mouseUp
  637.  
  638. %  show card picture
  639. This shows the picture on the current card.  For example :
  640.  
  641. on mouseUp
  642.   show card picture
  643. end mouseUp
  644.  
  645. %  hide background picture
  646. This hides the picture of the current background.  For example :
  647.  
  648. on mouseUp
  649.   hide background picture
  650. end mouseUp
  651.  
  652. %  show background picture
  653. This shows the picture of the current background.  For example :
  654.  
  655. on mouseUp
  656.   show background picture
  657. end mouseUp
  658.  
  659. %  lock Screen
  660. The lock  Screen command performs the same function as "set lockScreen to true."  For example:
  661.  
  662. on mouseUp
  663.   lock screen
  664. end mouseUp
  665.  
  666. %  unlock Screen [with visual effect]
  667. The unlock Screen command performs basically the same function as "set lockScreen to false".   In addition, unlock  Screen can take a single visual effect as an argument.  The visual effect is invoked as the screen is unlocked ("set lockScreen to false" doesn"t invoke visual effects).  
  668.  
  669. on mouseUp
  670.   set lockScreen to true
  671.   show card button 3
  672.   unlock screen with dissolve slowly
  673. end mouseUp
  674.  
  675. Note: Visual effects cannot be compounded when using unlock Screen.  The visual effects preceding the unlock Screen command shown below will not be executed until a Go command  is encountered (or until HyperCard has sufficient idle time to flush them).
  676.  
  677. on mouseUp
  678.   set lockScreen to true
  679.   show card button 3
  680.   visual effect barn door open   -- not invoked by unlock Screen
  681.   visual effect dissolve to black -- not invoked by unlock Screen
  682.   unlock Screen with checkerboard
  683. end mouseUp
  684.  
  685. In general, visual effects should be as close as possible to the Go command that will use them.  Here is an example of multiple visual effects in a single script:
  686.  
  687. on mouseUp
  688.  visual effect zoom open -- will execute with the Go command
  689.  go to next card
  690.  lock screen
  691.  show card field 3
  692.  unlock Screen with dissolve -- will work with the unlock Screen
  693.   -- command 
  694. end mouseUp 
  695.  
  696. %  select <button expression>
  697. Chooses the Button tool and selects the specified button.  For example:
  698.  
  699. select card button id 78 -- chooses the Button tool and selects the
  700.   -- button
  701. This works the same way as the following:
  702. choose button tool
  703. click at the loc of bkgnd button 3  -- select background button
  704.   -- number 3
  705.  
  706. This command is especially useful for operations on buttons covered by other objects.  It does not work for hidden buttons and works only when the user level is set to authoring (4) or higher.
  707.  
  708. %  select <field expression>
  709. Chooses the Field tool and selects the specified field.   This command is especially useful for operations on fields covered by other objects.  It does not work for hidden fields and works only when the user level is set to authoring (4) or higher.
  710.  
  711. %  select {before|after} <chunk expression> of <field expression>
  712. Selects (highlights) text in a specified field as though the user had clicked or dragged over the specified text.  "Before" or "after" can be used to place an insertion point at a specific location in a field.  A chunk expression can be used to select a range of words or characters in a specified field.  For example:
  713.  
  714. select word 3 of field 5 -- highlights the third word of background
  715.   -- field 5
  716. select before char 10 of field 3 -- sets the blinking insertion point
  717.   -- between characters 9
  718.   -- and 10 of background field 3
  719. select char 1 to 5 of bkgnd field 1 -- highlights the first five
  720.   -- characters of background field 1
  721. select word 2 to 4 of card field 3 -- highlights the second, third and
  722.   -- fourth words of card field 3
  723. select item 8 of bkgnd field 7 -- highlights the eighth item in card
  724.   -- field 3
  725.   -- remember, items are always separated by commas
  726.  
  727. If a chunk expression of the form "charStart > charEnd"
  728.  is used, a blinking insertion point will be set.  For example:
  729.  
  730. select char 10 to 9 of card field 13  -- sets an insertion point between
  731.   -- characters 9 and 10; no text is highlighted
  732.  
  733. If you "select" past the end of the text in the field, carriage returns will be inserted, and an insertion point will be set after the last return.  For example, if a field has only three lines of text in it, and you select line 5, two carriage returns will be inserted and your cursor will be set on line 5 of the field.
  734.  
  735. select line 5 of bkgnd field id 8 -- puts the insertion point at line 5
  736.   -- inserting any carriage returns needed to fill empty lines
  737.  
  738. Chunk expressions may also be used to select text in the message box.  For example:
  739.  
  740. select word 3 of msg -- highlights the third word of text in the
  741.   -- message box
  742.  
  743. %  select {before|after} text of <field expression>
  744. Selects all the text in a specified field .  "Before" or "after" can be used to place an insertion point at the beginning or end of the text in a field.  For example:
  745.  
  746. select after text of card field 7 -- sets the insertion point after the
  747.   -- last character of card field 7 
  748. select text of bkgnd field 3 -- highlights all the text of background
  749.   -- field 3
  750.  
  751. %  select <me | target>
  752. "Select" may take "me" or "target" as arguments for selecting objects or their contents.  For example:
  753.  
  754. on mouseUp
  755.   select me -- chooses the appropriate tool and selects the object
  756.   -- when the mouse clicks on it
  757. end mouseUp
  758.  
  759. on mouseEnter
  760.   select text of me -- selects all the text of a field when the mouse
  761.   -- enters it
  762. end mouseEnter
  763.  
  764. on mouseUp
  765.   select the target -- chooses the appropriate tool and selects the
  766.   -- object
  767. end mouseUp
  768.  
  769. %  select empty
  770. Use "select empty" to deselect highlighted text or remove a blinking insertion point.
  771.  
  772. %  set cursor to <watch | none | hand | arrow | iBeam | plus | cross | busy>
  773. Alternate cursors may be used via the "set cursor to <name or number of cursor>" command, but are shown only for the duration of the handler.  The cursor is always reset to the currently chosen tool (Browse, Button or Field) at idle.
  774.  
  775. on mouseUp
  776.   set cursor to watch -- show the watch cursor
  777.   repeat until the mouse is down
  778.     go to next card
  779.   end repeat
  780. end mouseUp
  781. set cursor to none -- show the HyperCard transparent cursor
  782. set cursor to hand -- show the HyperCard browse tool cursor 
  783. set cursor to arrow -- show the Macintosh arrow cursor
  784. set cursor to iBeam -- show the I-beam cursor
  785. set cursor to plus -- show the plus cursor
  786. set cursor to cross -- show the cross cursor
  787. The "busy" cursor is HyperCard"s beach ball.  The beach ball will turn 1/8 each time it is set, so it spins when set inside repeat loops.
  788.  
  789. on mouseUp
  790.   repeat for 100 times
  791.     set cursor to busy -- show HyperCard"s beach ball cursor (it will
  792.   -- spin)
  793.   add 1 to bkgnd field 1
  794.   end repeat
  795. end mouseUp
  796.  
  797. New HyperTalk Functions & Properties:
  798.  
  799. %  cantModify
  800. cantModify is a stack property which prevents users from compacting, deleting or changing the contents of a stack.  See the HyperCard Version 1.2 Release Notes Stack for a detailed description.  For stacks that are not otherwise locked (on a CD-ROM, locked floppy, locked by AppleShare or the Finder), scripts may get and set CantModify.  For example:
  801.  
  802. set cantModify of stack "MyStack" to true
  803.   -- prevents users from modifying the stack
  804.  
  805. %  userModify
  806. userModify is a global property which allows the user to type in fields or paint when the stack is locked.  Changes made by the user or script will be discarded upon leaving the card.  userModify is set to false whenever the user leaves a stack; it is ignored when a stack is unlocked. This example allows a user to type in a specific field on a locked stack:
  807.  
  808. on openField -- user can click in the specified field or press Tab
  809.   set userModify to true
  810. end openField
  811.  
  812. This next example prevents typing in fields which don"t contain the openField handler shown above:
  813.  
  814. on closeField -- user can click outside the specified field or press Tab
  815.   set userModify to false
  816. end closeField
  817.   -- closeField is only sent when the field contents have been changed
  818.  
  819. %  cantDelete
  820. Scripts may now get and set the cantDelete property for stacks, backgrounds and cards.  For example:
  821.  
  822. set cantDelete of this cd to true  -- prevents deletion of the card
  823. set cantDelete of this bg to true  -- prevents deletion of the
  824.   -- background
  825. set cantDelete of this stack to true  -- prevents deletion of the stack
  826.  
  827. %  showPict
  828. When showPict is true, the card or background picture is visible.  If false, the picture is hidden.  Scripts may get or set showPict.  For example:
  829.  
  830. get showPict of background 1
  831. if it is "true" then...
  832.  
  833. %  autoTab
  834. See the HyperCard Version 1.2 Release Notes stack for a functional description.  Scripts may get or set autoTab.  For example:
  835.  
  836. set autoTab of field 3 to true
  837.  
  838. %  number of cards of <background expression>
  839. This function returns the number of cards of a specified background.  For example:
  840.  
  841. get the number of cards of background 3
  842.  
  843. %  the foundText
  844. Returns the characters enclosed by the box after the Find command has executed.  For example:
  845.  
  846. find "Will"
  847. put the foundText -- puts "Will" or the whole word it was found
  848.   -- in(e.g. "William") into the msg box
  849.  
  850. %  the foundChunk
  851. Returns a chunk expression for where the string was found.  For example, if background field 6 contains the phrase "Now is the time," then:
  852.  
  853. find "Now"
  854. put the foundChunk -- puts "char 1 to 3 of bkgnd field 6" into the
  855.   -- message box
  856.  
  857. The foundChunk takes the form: char <number> to <number> of <card | bkgnd> field <number>.
  858.  
  859. %  the foundLine
  860. Returns an expression for  the starting line where the string was found.  For example, if line 2 of card field 3 contains the result of the Find:
  861.  
  862. find "Tiger"
  863. put the foundLine -- puts "line 2 of card field 3" into the message
  864.   -- box
  865.  
  866. The foundLine takes the form:  line <number> of <card | bkgnd> field <number>.  HyperCard recognizes only lines terminated by a carriage return.  A line that wraps and is displayed as two lines is still one line as far as HyperCard is concerned.
  867.  
  868. %  the foundField
  869. Returns an expression for the field where the string was found.   For example, if the Find command finds the text in the second line of the third card field:
  870.  
  871. put the foundField -- puts "card field 3" into the message box
  872.  
  873. The foundText, foundChunk, foundLine and foundField will be empty when a Find command fails because an empty string is returned.
  874.  
  875. %  the selectedText
  876. Similar to "the selection," returns the text that is currently highlighted but is not a container into which data can be stuffed.
  877.  
  878. %  the selectedChunk
  879. Returns a chunk expression for the range of currently highlighted characters.  For example, if a five letter word in card field 9 is selected:
  880.  
  881. put the selectedChunk -- puts "char 1 to 5 of card field 9" into the
  882.   -- message box.
  883.  
  884. The expression is of the form: char <number> to <number> of <card | background> field <number>.
  885.  
  886. %  the selectedLine
  887. Returns an expression for the line where the currently selected text is, using the form: 
  888.  
  889. line <number> of <card | background> field <number>.
  890.  
  891. %  the selectedField
  892. Returns an expression for the field where the currently selected text is of the form:
  893.  
  894. <card | background> field <number>.
  895.  
  896. %  left of <button expression> <field expression> <window expression>
  897. Returns item 1 of the rect (left, top, right, bottom) of a specified object.  For example:
  898.  
  899. put left of card button id 456 -- puts the value of the left coordinate
  900.   --  of the rectangle of card button id 456
  901. set left of bkgnd field 5 to 20 -- sets the left coordinate of the
  902.   -- rectangle of background field 5 to 20 pixels from the left edge of 
  903.   -- HyperCard"s window
  904. put left of the card window into MyVar -- puts the left coordinate of
  905.   -- the HyperCard window into the local variable "MyVar"
  906. get left of tool window -- returns the left coordinate of the tool
  907.   -- window
  908.  
  909. "Set <left | top | right | bottom> of <expression> to <number>"  will move the object so that the specified  parameter is at the specified coordinate.  It is also much faster than using "set loc of <expression>."
  910.  
  911. HyperCard"s card window uses global coordinates from the Macintosh screen where 0,0 is the top left corner of the screen the menu bar is in.  HyperCard windows  (card, message, tool and pattern) and objects (button, field) and the Loc (mouseLoc, clickLoc)  use local coordinates based on HyperCard"s window where 0,0 is the top left corner of HyperCard"s card window.  HyperCard buttons and fields set with negative coordinates are preserved, but cannot be seen or get mouse clicks.
  912.  
  913. %  top of <button expression> <field expression> <window expression>
  914. Returns item 2 of the rect of a specified object. 
  915.  
  916. %  right of <button expression> <field expression> <window expression>
  917. Returns item 3 of the rect of a specified object. 
  918.  
  919. %  bottom of <button expression> <field expression> <window expression>
  920. Returns item 4 of the rect of a specified object. 
  921.  
  922. %  topLeft of <button expression> <field expression> <window expression>
  923. Returns items 1 and 2 of the rect (l, t, r, b) of a specified object.  This is the top left corner of the object. 
  924.  
  925. %  bottomRight of <button expression> <field expression> <window expression>
  926. Returns items 3 and 4 of the rect of a specified object.  This is the  bottom right corner of the object. 
  927.  
  928. %  botRight of <button expression> <field expression> <window expression>
  929. botRight is an abbreviation for bottomRight.
  930.  
  931. %  width of <button expression> <field expression> <window expression>
  932. Returns the width of the specified object.  For example:
  933.  
  934. put width of card button id 456 -- puts the width of card button 
  935.   -- id 456
  936. set width of bkgnd field 5 to 90 -- sets the width of background 
  937.   --  field 5 to 90 pixels
  938. put width of the card window into ABC -- puts the width of
  939.   -- HyperCard"s window into the local variable "ABC"
  940.  
  941. When the script changes the width of the specified object, HyperCard preserves the loc (center coordinate) of the object, divides the specified width by 2, sets the left to the dividend and sets the right to (left + the specified width).  For example:
  942.  
  943. get the width of card button 18 -- put the width of the button into it
  944. set width of card button 18 to it + 20  
  945. -- set left to (item 1 of loc - ((it + 20)/2))
  946.  
  947. When the width of a button or field is changed by an odd amount, HyperCard rounds the dividend down and adds the remainder (1) to the right coordinate.
  948. When the width of a button or field equals 0 or goes negative, the object continues to exist, but cannot be seen or get mouse clicks.
  949.  
  950. %  height of <button expression> <field expression> <window expression>
  951. Returns the height of the specified object.
  952. When the script changes the height of the specified object, HyperCard preserves the loc (center coordinate) of the object, divides the specified height by 2, sets the top to the dividend and sets the bottom to (top + the specified height).  For example:
  953.  
  954. get the height of bkgnd field 11 -- put the height of the field into it
  955. set width of bkgnd field 11 to it + 36
  956.   -- set top to (item 2 of loc - ((it+36)/2))
  957.  
  958. When the height of a button or field is changed by an odd amount, HyperCard rounds the dividend down and adds the remainder (1) to the bottom coordinate.
  959. When the height of a button or field equals 0 or goes negative, the object continues to exist, but cannot be seen or get mouse clicks.
  960. Neither the height nor width of HyperCard"s window objects (card, message, tools, pattern) can be changed.
  961.  
  962. %  the screenRect
  963. Returns the rect of the screen being used (left, top, right, bottom) in global coordinates.  When there is more than one monitor, the function returns values for the screen HyperCard"s menu bar is in.
  964.  
  965. %  the long version [of HyperCard]
  966. Returns the HyperCard version number in the standard Macintosh version resource (see Inside Macintosh for explanations of the format).  In HyperCard 1.2.1:
  967.  
  968. put the long version  -- puts "01208000" into the message box.
  969.  
  970. %  the version of <stack expression>
  971. Returns a five item string listing:
  972. 1.  the version of HyperCard which created the stack.
  973. 2.  the version of HyperCard last used to compact the stack.
  974. 3.  the oldest version of HyperCard which changed the stack since it was last compacted.
  975. 4.  the version of HyperCard which last changed the stack.
  976. 5.  most recent modification date of the stack (in seconds)
  977. Note:  This item is only updated when the stack is closed, not as changes are made.  To confirm a change to the modification date, leave the stack, then reopen it and check item 5 of the long version of the stack.
  978. Items 1 to 4  will be set to 00000000 if the version of HyperCard is less than 1.2.1.
  979. For a stack created with HyperCard version 1.1, then edited and compacted with version 1.2.1 things would look something like this:
  980. put the version of stack "old stack" -- would put
  981.   --"00000000,01208000,01208000,01208000,2660687462"
  982.   -- into the message box
  983. Scripts can convert item 5 into a date and time to determine when the stack was last modified, or check items 1 through 4 to find out whether it had been created, changed or compacted with a version of HyperCard older than 1.2.1.
  984.  
  985. New HyperTalk Operator:
  986.  
  987. %  within
  988. Takes the form: <point expression> is {not} within <rect expression> and tests whether a point is within a specific rectangle.  For example:
  989.  
  990. on mouseUp
  991.   -- tests the mouseLoc and beeps if it is not inside the button rect
  992.   wait until the mouseLoc is not within rect of me
  993.   repeat until the mouseLoc is within rect of me
  994.     beep
  995.   end repeat
  996. end mouseUp
  997.  
  998. XCMD Improvements
  999.  
  1000. If an XCMD is called with more than 16 parameters, an error message will appear.
  1001.  
  1002. outArgs[1] is guaranteed to be NIL if it is not a valid handle.  In previous versions of HyperCard, XCMDs had to check for a result of xresFail to know if you had an invalid handle.
  1003.  
  1004. Errors from XCMDs no longer present dialogs to the user.   As before, a result of xresFail informs the XCMD that an error has occurred.  XCMDs are now free to try evaluating invalid expressions or sending messages that no one receives.  They can tell from the result field whether they succeeded or not.
  1005.  
  1006. XCMDs can continue running even after an error has occurred.  Previously, once an XMCD had evaluated an invalid expression, sent a message that was not caught, or otherwise caused an error, all subsequent callbacks would do nothing.   Subsequent callbacks continue to work in HyperCard 1.2.1.
  1007.  
  1008. Switching between Browse, Button and Field tools:
  1009.  
  1010. Rotating quickly between tools:
  1011. %  Command-Tab-Tab (in rapid succession) chooses the
  1012.     Button tool.
  1013. %  Command-Tab-Tab-Tab (in rapid succession) chooses 
  1014.     the Field tool.
  1015. Command-Tab chooses the Browse tool (as always).
  1016.  
  1017. Peeking at Scripts:
  1018. The user level must be set to Scripting to "peek" at scripts.
  1019.  
  1020. In the Browse tool:
  1021.  
  1022. Command-Option mouse click P Users can see scripts for any button by holding down the Command key and Option key, then clicking the mouse on the button they want to "peek" at.  Once the script is visible, the script editor may be closed quickly by holding down Command-Option, then clicking the mouse or pressing any key.  If the script has been changed, HyperCard will show an alert asking whether the changes should be saved.
  1023.  
  1024. Command-Option-c, -b, -s.   While holding down the Command and Option keys, pressing "c", "b", or "s" will bring up the card, background or stack scripts respectively.  Once the script is visible, the script editor may be closed quickly by holding down Command-Option, then clicking the mouse or pressing any key.  If the script has been changed, HyperCard will ask whether the changes should be saved.
  1025.  
  1026. Shift-Command-Option-click lets you peek at all field and button scripts (except hidden ones).
  1027.  
  1028. In the Button Tool, Command-Option-click lets you peek at button scripts (except hidden buttons).
  1029.  
  1030. In the Field Tool, Command-Option-click lets you peek at field scripts (except hidden fields).
  1031.  
  1032. Performance and Other Improvements:
  1033.  
  1034. %  If there is a selection in a locked field, any typing or pasting goes to the message box.  The highlighted text in the field will be deselected.  A blinking insertion point in the field will be cleared.
  1035. %  When a handler locks the screen, a number of changes will no
  1036.     longer be visible to the user:
  1037. %  The cursor won"t change when tools change.
  1038. %  The pattern palette won"t change when new patterns are chosen.
  1039. %  The tool palette won"t change when new tools are chosen.
  1040. %  The menu bar doesn"t change when menu choices are made (for
  1041.     example, when switching in and out of painting tools).
  1042. %  The card window title bar doesn"t change when the handler goes
  1043.     to another stack.
  1044.  
  1045. When the screen is unlocked, changes will be updated.
  1046. %  Using the Go command to go to a specific card id is much faster in
  1047.     HyperCard 1.2.1.  To take advantage of this, the stack must be
  1048.     compacted with version 1.2.1.
  1049. %  Using  the command "Go first | next | last | any card of  background
  1050.     "foo"" is much faster in HyperCard 1.2.1.  Again, the stack must
  1051.     be compacted with version 1.2.1.
  1052. %  Switching from the Browse, Button or Field tools to the Painting
  1053.     tools is much faster.
  1054. %  The container "the selection" will now hold 32K of data. 
  1055. %  For operations on fields, "me" can now be used as a container.  In
  1056.     the past, "me" always referred to the object - not to its contents. 
  1057.     In HyperCard 1.2.1, "me" can refer to the object or its contents.
  1058.  
  1059. Version 1.0.1 and 1.1:
  1060.  
  1061. get the name of me -- returns name of the the object
  1062. put "Fred" into me -- is incorrect syntax
  1063. put me into MyVar  -- is incorrect syntax
  1064.  
  1065. Version 1.2.1:
  1066.  
  1067. get the name of me -- returns name of the object
  1068.  
  1069. put "Fred" into me  -- or
  1070. put "Fred" into line 3 of me
  1071.   -- puts the string "Fred" into the field (if "me" refers to a field or
  1072.   -- variable)
  1073.  
  1074. put me into MyVar 
  1075.   -- puts the contents of the field into the 
  1076.   --variable MyVar
  1077.  
  1078. %   In the past (for operations on fields) "the target" always referred to the object - not to its contents .  In HyperCard 1.2.1, "target"  refers to the contents of "the target".  "The target" continues to refer explicitly to the object itself.
  1079.  
  1080. Version 1.0.1 and 1.1:
  1081.  
  1082. put the target   -- puts the name of the object that last received a 
  1083.                         -- message.
  1084.  
  1085. put target into MyVar  -- is incorrect syntax
  1086. put "Fred" into target -- is incorrect syntax
  1087.  
  1088. Version 1.2.1:
  1089.  
  1090. put the target  -- puts the name of the object that last received a
  1091.   -- message
  1092.  
  1093. put target into MyVar
  1094.   -- puts the contents of the field into the variable MyVar.
  1095.  
  1096. put "Fred" into target -- puts the string "Fred" into the field.
  1097. put value of the target -- is equivalent to "put target"
  1098.  
  1099. Note:  These changes apply only to operations on fields, not to buttons, cards, backgrounds or stacks.
  1100.  
  1101. %  Clicking the mouse in a text field while holding the Shift key down does the following:
  1102. When there is already text in the field:  If the mouse click is below the last line of characters  the insertion point is set after the last character in the field .  If the mouse click is higher than the last line of characters, the text from the mouse location to the last character will be selected.
  1103. If the field is empty, the insertion point will be set at the beginning of the first line of the field.
  1104. In versions 1.0.1 and 1.1 of HyperCard, clicking the mouse below the last line of a field inserts Return characters in the empty lines above the location of the mouse click.
  1105.  
  1106. %  Under MultiFinder 6.0, HyperCard will switch to other
  1107.      applications using HyperTalk"s "Open" command, if    
  1108.      the desired application is already open.
  1109.  
  1110. %  When the message box is empty or has spaces in it, 
  1111.      HyperCard no longer complains when the Return key is
  1112.      pressed.
  1113.  
  1114. %  The setGlobal glue routine will now create a global 
  1115.      variable using the name you specify if it can"t find an 
  1116.      existing global with that name.
  1117.  
  1118. %  If paint images overlapping a field are transparent, the 
  1119.      card will print at high quality on the LaserWriter (not 
  1120.      72 dpi).
  1121.  
  1122. %  The "Open Stack ...,  New Stack..." and "Save a Copy..."
  1123.      menu items are now available while a painting tool is
  1124.      selected.
  1125.  
  1126. User Visible Enhancements:
  1127.  
  1128. %  When text has been selected in one field, and the user
  1129.      clicks on another, locked field, the selection is now
  1130.      maintained.
  1131. %  Tabbing into a field will now select up to 32K (or the
  1132.      entire contents of the field).
  1133. %  When deleting a card, openCard and closeCard mes
  1134.      sages are no longer sent.
  1135. %  In the "Stack Info..." dialog, the size of the stack now
  1136.     includes the resource fork.
  1137. %  When "Copy Current Background" is not checked in the
  1138.     "New Stack..." dialog, HyperCard no longer copies the 
  1139.      resource fork of existing stacks with the same name.
  1140. %  Report printing on the LaserWriter and ImageWriter II
  1141.      no longer occasionally skips pages, prints random data
  1142.      or incorrectly wraps words in mailing labels.
  1143.  
  1144. Miscellaneous Notes:
  1145.  
  1146. Write Protected (Locked) Media and Stacks
  1147. There are five ways to lock or write-protect a stack:
  1148.  
  1149. 1.  Put it on a CD-ROM.
  1150.  
  1151. 2.  Locked floppy disk-setting the write-protect tab on a 
  1152.      floppy disk.
  1153.  
  1154. 3.  Putting the stack into a read-only folder under 
  1155.      AppleShare, or limiting AppleShare access privileges 
  1156.      for the stack itself.
  1157.  
  1158. 4.  Checking the "locked" box in the stack"s Get Info 
  1159.      window in the Finder.
  1160.  
  1161. 5.  Setting cantModify to true in a script or by checking the
  1162.      Can"t Modify box in the Protect Stack dialog  (however,
  1163.      setting cantModify to true in a stack is not sufficient to
  1164.      allow multiple user access).
  1165.  
  1166. HyperCard detects the first four conditions and automatically sets cantModify and cantDelete to true.  HyperCard shows a  small padlock icon after the rightmost menu item when a stack is locked.
  1167.  
  1168. When a stack is locked and userModify is false, certain menu items are grayed out :
  1169.  
  1170. File                                Edit                    Objects    
  1171. -----                              -----                       -----
  1172. Compact Stack                Cut                New Button
  1173. Delete StackI            Paste            New Field
  1174. Import Paint...            Clear                       New Background
  1175.                                     New Card
  1176.                     Delete Card
  1177.                                     Cut Card
  1178.                     Text Style
  1179.  
  1180. Scripts can determine whether the first four locking conditions are preventing permanent changes by testing cantModify.  For example, a script can attempt to set cantModify to false, then check its state.  For example:
  1181.  
  1182. on mouseUp
  1183.   set cantModify of this stack to false
  1184.   get cantModify of this stack
  1185.   if it is true then ... -- the stack is on locked media
  1186.   else  -- the stack isn"t on locked media, and can be modified...
  1187.   end if
  1188. end mouseUp
  1189.  
  1190. If the cantModify property of a stack is false before being placed on read-only media, and the stack is later copied to read-write media, cantModify will remain false.
  1191.  
  1192. Design Considerations:
  1193.  
  1194. Version Requirements - Using HyperCard 1.2.1's new commands will require the stack to be run using version 1.2.1.  If none of the new syntax, synonyms, and commands are used, stacks created with version 1.2.1  will work fine with HyperCard versions 1.1 and 1.0.1.  Compacting a stack with version 1.2.1 will neither help nor hinder its performance with other versions.
  1195.  
  1196. HyperTalk"s function "the version" can be used to determine which version of HyperCard you are running under.  For example:
  1197. if the version < "1.2" then set lockScreen to false
  1198. else unlock Screen with dissolve 
  1199.  
  1200. Read-only media and stacks P No special commands are required to read a locked stack.  But bear two things in mind when creating stacks that will be locked:  First, all changes generated by scripts (such as showing a pop-up field) disappear when any move is made to another card.  Second, assume the stack will be unlocked somewhere down the line.  For example, if you have a field which pops up with a helpful tip for the user, don"t rely on the behavior of the locked stack to hide the field when the user is through with it.  Clean up after yourself.
  1201. Here"s a list of things which cannot be done by either users or scripts on locked media:
  1202.     %  make new cards
  1203.     %  delete, cut or paste cards
  1204.     %  make new backgrounds
  1205.     %  compact the stack
  1206.     %  delete the stack
  1207.     %  edit patterns
  1208.     %  change the name of a stack
  1209.     %  change any scripts
  1210.     %  sort the stack
  1211.  
  1212. Changes to locked stacks are discarded by:
  1213.     %  choosing New Stack..., Open Stack...,  Save a     
  1214.         Copy..., Print Stack... or Print Report...  from the File menu
  1215.     %  toggling to or from the background
  1216.     %  sublaunching another application (using the     
  1217.          open command)
  1218.     %  leaving the current card
  1219.     %  opening another stack
  1220.     %  quitting HyperCard
  1221.  
  1222. When cantModify is true, setting it to false discards any changes.  When cantModify is false, setting it to false saves recent changes to the stack then sets the property. 
  1223.  
  1224. "Print Stack..." rotates through the cards in the stack while generating the print job, thus any changes to a specific card in a locked or write-protected stack will be discarded before printing.
  1225.  
  1226. Multiple Users P Several users may read a stack if it"s on a CD-ROM, set for read only access, or locked by the Finder.  Setting cantModify to true in a stack is not sufficient to allow multiple user access.  If one user opens a stack with read-write access (even with cantModify set to true), no other users can open it.  
  1227.  
  1228. Hidden pictures P(Card or background) remain invisible until the user attempts to edit them.  At that time, HyperCard shows an alert asking whether the picture should be shown.  Scripts may make changes to a picture without showing the picture (no alerts will appear).
  1229.  
  1230. Copying Text and Graphics P Users may set an insertion point in a field to select or copy text, but generally can"t type into fields on locked stacks.  The selection tools may be used to select or copy graphics from a locked stack.
  1231.  
  1232. Using userModify P If a script sets userModify to true, users can type in fields or paint on the card or background.  UserModify"s default setting is false, and it is reset whenever you close or open a stack.  (If you want to save the information the user entered, store it in a global variable.)
  1233.  
  1234. Printing P Cards on a locked stack can be printed in the usual way.  If a card image is temporarily altered by a script or user, the image displayed on the screen will be printed (when "Print Card" is selected from the File menu), not the original card on the disk.
  1235.  
  1236. ------------------------------------------------------------------------ 
  1237. Editor's Final Comments
  1238. by
  1239. David Leffler
  1240.  
  1241. We hope you have enjoyed reading this latest issue of WINDOID and have found it to be interesting and informative. We care enough to take the time to give you the most up-to-date information about HyperCard, and we would like to make a request for a little of your time. There is a form that follows this editorial; please fill it out if you will. We are very interested in hearing from you. What sort of stacks are you using, what kind of stacks are you creating, and what are your joys and frustrations in using HyperCard.
  1242.  
  1243. You have the unique opportunity to communicate directly with Bill, Dan, and the entire HyperCard development team. We really want to know what you would like to see in HyperCard and are more than willing to give you what you want. What we need to make this happen is your input. Let us know what you think. We can address it in WINDOID or perhaps the next revision of HyperCard. You can make a difference in the world by communicating with us. DonUt pass up the opportunity!
  1244.  
  1245. If you would like information about AHUG, please send a stamped-
  1246. self-addressed-envelope to:
  1247.  
  1248. AHUG c/o Bryan K. Carter
  1249. Apple Computer Co, Inc.
  1250. MS/27-AHUG
  1251. 20525 Mariani Ave. 
  1252. Cupertino, CA 95014
  1253.  
  1254. ------------------------------------------------------------------------
  1255. THE FORM
  1256.  
  1257. If you have a bug, suggestion, comment, or just want to know the best way to do something in HyperCard, you can fill out the form and send it to:
  1258.  
  1259. AHUG c/o David Leffler
  1260. Apple Computer, Inc.
  1261. MS/27-AQ
  1262. 20525 Mariani Ave.
  1263. Cupertino, CA 95014
  1264.  
  1265. Or copy the format and
  1266. AppleLink* it to:
  1267. HYPERBUG$
  1268.  
  1269.  
  1270. TELL HYPERCARD
  1271. You can use this form to notify the HyperCard team of problems, bugs, and enhancement requests.
  1272.  
  1273. THE FORM:
  1274.  
  1275. Please use the following form to make a difference in the world:
  1276.  
  1277. Date:
  1278. Name:
  1279. Address:
  1280. Phone #:
  1281. Versions of:
  1282. a.  HyperCard:
  1283. b.  Associated software:
  1284. c.  System Software:
  1285. 1. System
  1286. 2. Finder
  1287. 3. ImageWriter file
  1288. 4. LaserWriter file
  1289. 5. Any others
  1290. Type of Macintosh:
  1291. Peripherals:
  1292. Description of problem, suggestions or comments:
  1293.  
  1294.  
  1295. If you have some information for us please fill this form out as completely as possible and send it to us.  You will be glad you did!
  1296.  
  1297. ----------------------------------------
  1298. Submissions to: hyper-hackers@plaid.sun.com
  1299. Administrivia to: hyper-hackers-request@plaid.sun.com
  1300. UUCP: {decwrl,hplabs,ihnp4}!sun!plaid!hyper-hackers{-request}
  1301. Archives can be gotten from the archive-server.
  1302. To get information on the archive-server, send mail to:
  1303. archive-server@plaid.sun.com -or- sun!plaid!archive-server
  1304. with a subject line of help
  1305.